package com.oauth.google.server.service;

import javax.annotation.PostConstruct;

import oauth.signpost.OAuthConsumer;
import oauth.signpost.basic.DefaultOAuthConsumer;
import oauth.signpost.signature.HmacSha1MessageSigner;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.google.gdata.client.authn.oauth.GoogleOAuthHelper;
import com.google.orkut.client.api.BirthdayNotificationTx;
import com.google.orkut.client.api.FriendTxFactory;
import com.google.orkut.client.api.GetFriendTx;
import com.google.orkut.client.api.GetProfileTx;
import com.google.orkut.client.api.GetScrapsTx;
import com.google.orkut.client.api.ProfileTxFactory;
import com.google.orkut.client.api.ScrapTxFactory;
import com.google.orkut.client.api.Transaction;
import com.google.orkut.client.api.UpdateProfileTx;
import com.oauth.common.server.beans.OAuthConfigBean;
import com.oauth.google.client.beans.orkut.OrkutBirthdayDetails;
import com.oauth.google.client.beans.orkut.OrkutFriendDetails;
import com.oauth.google.client.beans.orkut.OrkutScrapDetails;
import com.oauth.google.client.beans.orkut.OrkutUser;
import com.oauth.google.server.conf.OrkutInfoBean;
import com.oauth.google.server.constants.GoogleServiceType;
import com.oauth.google.server.shared.orkut.AuthorizedChannel;
import com.oauth.google.server.shared.orkut.OrkutUtil;
import com.oauth.service.application.ApplicationService;
import com.oauth.service.global.beans.OAuthAccessToken;

@Service
public class OrkutOAuthServiceImpl extends AbstractGoogleOAuthService implements OrkutOAuthService {

	@Autowired
	private ApplicationService applicationService;

	@Autowired
	@Qualifier("orkutConfig")
	private OAuthConfigBean mOAuthConfigBean;

	@Autowired
	private OrkutInfoBean orkutInfoBean;

	@PostConstruct
	public void initialise() {
	}

	/**
	 * @param pOAuthConfigBean
	 *            the oAuthConfigBean to set
	 */
	public void setOAuthConfigBean(OAuthConfigBean pOAuthConfigBean) {
		mOAuthConfigBean = pOAuthConfigBean;
	}

	private <T extends Transaction> T getTransaction(Long pMemberId, T pTx) throws Exception {
		OAuthConsumer oauthConsumer = getOAuthConsumer(pMemberId);
		new AuthorizedChannel().add(pTx).run(oauthConsumer);
		return pTx;
	}

	private OAuthConsumer getOAuthConsumer(Long pMemberId) throws Exception {
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		OAuthConsumer oauthConsumer = new DefaultOAuthConsumer(mOAuthConfigBean.getConsumerKey(),
				mOAuthConfigBean.getConsumerSecret());
		oauthConsumer.setMessageSigner(new HmacSha1MessageSigner());
		oauthConsumer.setTokenWithSecret(accessToken.getToken(), accessToken.getTokenSecret());
		return oauthConsumer;
	}

	public OrkutFriendDetails getFriends(Long pMemberId) throws Exception {
		FriendTxFactory friendTxFactory = new FriendTxFactory();
		GetFriendTx getFriendsTx = friendTxFactory.getSelfFriends();
		getTransaction(pMemberId, getFriendsTx);
		return OrkutUtil.getOrkutFriends(getFriendsTx);
	}

	public OrkutBirthdayDetails getUpcomingBirthdays(Long pMemberId) throws Exception {
		FriendTxFactory friendTxFactory = new FriendTxFactory();
		BirthdayNotificationTx birthdayNotificationTx = friendTxFactory.getBirthdayNotification();
		getTransaction(pMemberId, birthdayNotificationTx);
		return OrkutUtil.getBirthdayNotifications(birthdayNotificationTx);
	}

	public OrkutScrapDetails getScraps(Long pMemberId) throws Exception {
		ScrapTxFactory scrapTxFactory = new ScrapTxFactory();
		GetScrapsTx getScrapsTx = scrapTxFactory.getSelfScraps();
		getTransaction(pMemberId, getScrapsTx);
		return OrkutUtil.getOrkutScraps(getScrapsTx);
	}

	public OrkutUser getLoggedInUserInfo(Long pMemberId) throws Exception {
		ProfileTxFactory profileFactory = new ProfileTxFactory();
		GetProfileTx getProfileTx = profileFactory.getSelfProfile();
		getTransaction(pMemberId, getProfileTx);
		OrkutUser user = OrkutUtil.getOrkutUser(getProfileTx.getProfile());
		getProfileTx = profileFactory.getSelfProfile().alsoGetStatus();
		getTransaction(pMemberId, getProfileTx);
		user.setStatus(getProfileTx.getProfile().getStatus());
		return user;
	}

	@Override
	public void updateStatus(String pText, Long pMemberId) throws Exception {
		ProfileTxFactory profileFactory = new ProfileTxFactory();
		UpdateProfileTx updateProfileTx = profileFactory.updateSelfProfile().setStatus(pText);
		getTransaction(pMemberId, updateProfileTx);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getApplicationKey
	 * ()
	 */
	@Override
	protected Long getApplicationKey() {
		return orkutInfoBean.getKey();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.oauth.google.server.service.AbstractGoogleOAuthService#
	 * getApplicationService()
	 */
	@Override
	protected ApplicationService getApplicationService() {
		return applicationService;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getScope()
	 */
	@Override
	protected String getScope() {
		return GoogleServiceType.Orkut.getScope();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getOAuthHelper
	 * ()
	 */
	@Override
	protected GoogleOAuthHelper getOAuthHelper() {
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.oauth.google.server.service.AbstractGoogleOAuthService#getOAuthConfigBean
	 * ()
	 */
	@Override
	protected OAuthConfigBean getOAuthConfigBean() {
		return mOAuthConfigBean;
	}
}
